From 00cc829c91e80aff8525bbceef8058162061e7a5 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Fri, 13 Aug 2004 15:45:51 +0000 Subject: [PATCH] bitkeeper revision 1.1159.27.1 (411ce22fF0PE2whpAPrucFCnOwpOIw) save/restore for linux 2.6 (not quite there yet) --- .../arch/xen/i386/kernel/irq.c | 6 +++++- .../arch/xen/kernel/reboot.c | 5 ++++- tools/libxc/xc_linux_restore.c | 3 ++- tools/libxc/xc_linux_save.c | 21 +++++++++++++------ xen/arch/x86/x86_32/mm.c | 5 ++++- xen/include/asm-x86/mm.h | 6 ++++-- 6 files changed, 34 insertions(+), 12 deletions(-) diff --git a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/irq.c b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/irq.c index 6698c8ca5f..b79c689474 100644 --- a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/irq.c +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/irq.c @@ -694,6 +694,7 @@ void free_irq(unsigned int irq, void *dev_id) p = &desc->action; for (;;) { struct irqaction * action = *p; + if (action) { struct irqaction **pp = p; p = &action->next; @@ -710,7 +711,10 @@ void free_irq(unsigned int irq, void *dev_id) /* Wait to make sure it's not being used on another CPU */ synchronize_irq(irq); - kfree(action); + +#define SA_STATIC_ACTION 0x01000000 /* Is it our duty to free the action? */ + if (!(action->flags & SA_STATIC_ACTION)) + kfree(action); return; } printk("Trying to free free IRQ%d\n",irq); diff --git a/linux-2.6.7-xen-sparse/arch/xen/kernel/reboot.c b/linux-2.6.7-xen-sparse/arch/xen/kernel/reboot.c index d3679ef76b..a3d46cb231 100644 --- a/linux-2.6.7-xen-sparse/arch/xen/kernel/reboot.c +++ b/linux-2.6.7-xen-sparse/arch/xen/kernel/reboot.c @@ -107,7 +107,11 @@ static void __do_suspend(void) memcpy(&start_info, &suspend_record->resume_info, sizeof(start_info)); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + set_fixmap_ma(FIX_SHARED_INFO, start_info.shared_info); +#else set_fixmap(FIX_SHARED_INFO, start_info.shared_info); +#endif HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO); @@ -134,7 +138,6 @@ static void __do_suspend(void) __sti(); - out: if ( suspend_record != NULL ) free_page((unsigned long)suspend_record); diff --git a/tools/libxc/xc_linux_restore.c b/tools/libxc/xc_linux_restore.c index 62050c83eb..5ccbb6e225 100644 --- a/tools/libxc/xc_linux_restore.c +++ b/tools/libxc/xc_linux_restore.c @@ -112,7 +112,7 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt) unsigned long *region_mfn = NULL; /* A temporary mapping, and a copy, of one frame of guest memory. */ - unsigned long *ppage; + unsigned long *ppage = NULL; /* A copy of the pfn-to-mfn table frame list. */ unsigned long pfn_to_mfn_frame_list[1024]; @@ -530,6 +530,7 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt) xcio_error(ioctxt, "GDT entry count out of range"); goto out; } + for ( i = 0; i < ctxt.gdt_ents; i += 512 ) { pfn = ctxt.gdt_frames[i]; diff --git a/tools/libxc/xc_linux_save.c b/tools/libxc/xc_linux_save.c index c2482ef2b1..1d4a054257 100644 --- a/tools/libxc/xc_linux_save.c +++ b/tools/libxc/xc_linux_save.c @@ -320,7 +320,7 @@ int xc_linux_save(int xc_handle, XcIOContext *ioctxt) unsigned long page[1024]; /* A copy of the pfn-to-mfn table frame list. */ - unsigned long *live_pfn_to_mfn_frame_list; + unsigned long *live_pfn_to_mfn_frame_list = NULL; unsigned long pfn_to_mfn_frame_list[1024]; /* Live mapping of the table mapping each PFN to its current MFN. */ @@ -330,13 +330,13 @@ int xc_linux_save(int xc_handle, XcIOContext *ioctxt) unsigned long mfn_to_pfn_table_start_mfn; /* Live mapping of shared info structure */ - shared_info_t *live_shinfo; + shared_info_t *live_shinfo = NULL; /* base of the region in which domain memory is mapped */ unsigned char *region_base = NULL; /* A temporary mapping, and a copy, of the guest's suspend record. */ - suspend_record_t *p_srec; + suspend_record_t *p_srec = NULL; /* number of pages we're dealing with */ unsigned long nr_pfns; @@ -679,6 +679,7 @@ int xc_linux_save(int xc_handle, XcIOContext *ioctxt) for ( j = 0; j < batch; j++ ){ if ( (pfn_type[j] & LTAB_MASK) == XTAB ){ DDPRINTF("type fail: page %i mfn %08lx\n",j,pfn_type[j]); +printf("type fail: page %i mfn %08lx\n",j,pfn_type[j]); continue; } @@ -829,7 +830,7 @@ int xc_linux_save(int xc_handle, XcIOContext *ioctxt) goto out; } - printf("SUSPPPPPPPP flags %08lx shinfo %08lx eip %08lx esi %08lx\n", + printf("SUSPEND flags %08lx shinfo %08lx eip %08lx esi %08lx\n", op.u.getdomaininfo.flags, op.u.getdomaininfo.shared_info_frame, ctxt.cpu_ctxt.eip, ctxt.cpu_ctxt.esi ); @@ -894,9 +895,10 @@ printf("nrpfns according to suspend record is %ld\n", p_srec->nr_pfns ); xcio_error(ioctxt, "Suspend record is not in range of pseudophys map"); goto out; } - + /* Canonicalise each GDT frame number. */ for ( i = 0; i < ctxt.gdt_ents; i += 512 ) { + ctxt.gdt_frames[i], live_mfn_to_pfn_table[ctxt.gdt_frames[i]]); if ( !translate_mfn_to_pfn(&ctxt.gdt_frames[i]) ) { xcio_error(ioctxt, "GDT frame is not in range of pseudophys map"); goto out; @@ -916,9 +918,16 @@ printf("nrpfns according to suspend record is %ld\n", p_srec->nr_pfns ); xcio_error(ioctxt, "Error when writing to state file (1)"); goto out; } - munmap(live_shinfo, PAGE_SIZE); + printf("Everything saved OK!\n"); out: + + if ( live_shinfo ) munmap(live_shinfo, PAGE_SIZE); + if ( p_srec ) munmap(p_srec, sizeof(*p_srec)); + if ( live_pfn_to_mfn_frame_list ) munmap(live_pfn_to_mfn_frame_list, PAGE_SIZE); + if ( live_pfn_to_mfn_table ) munmap(live_pfn_to_mfn_table, nr_pfns*4 ); + if ( live_mfn_to_pfn_table ) munmap(live_mfn_to_pfn_table, PAGE_SIZE*1024 ); + if ( pfn_type != NULL ) free(pfn_type); DPRINTF("Save exit rc=%d\n",rc); return !!rc; diff --git a/xen/arch/x86/x86_32/mm.c b/xen/arch/x86/x86_32/mm.c index a38cb6b0ad..6c5b26f87c 100644 --- a/xen/arch/x86/x86_32/mm.c +++ b/xen/arch/x86/x86_32/mm.c @@ -262,6 +262,10 @@ long set_gdt(struct domain *d, int i, nr_pages = (entries + 511) / 512; struct desc_struct *vgdt; + vgdt = map_domain_mem(frames[0] << PAGE_SHIFT); + memset( vgdt + FIRST_RESERVED_GDT_ENTRY, 0, + NR_RESERVED_GDT_ENTRIES*8); + /* Check the new GDT. */ for ( i = 0; i < nr_pages; i++ ) { @@ -272,7 +276,6 @@ long set_gdt(struct domain *d, } /* Copy reserved GDT entries to the new GDT. */ - vgdt = map_domain_mem(frames[0] << PAGE_SHIFT); memcpy(vgdt + FIRST_RESERVED_GDT_ENTRY, gdt_table + FIRST_RESERVED_GDT_ENTRY, NR_RESERVED_GDT_ENTRIES*8); diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h index 7ee6b24bff..cc68ce083e 100644 --- a/xen/include/asm-x86/mm.h +++ b/xen/include/asm-x86/mm.h @@ -249,8 +249,10 @@ static inline int get_page_type(struct pfn_info *page, u32 type) /* Try to validate page type; drop the new reference on failure. */ if ( unlikely(!alloc_page_type(page, type)) ) { - DPRINTK("Error while validating pfn %08lx for type %08x\n", - page_to_pfn(page), type); + DPRINTK("Error while validating pfn %08lx for type %08x. caf=%08x taf=%08x\n", + page_to_pfn(page), type, + page->u.inuse.count_info, + page->u.inuse.type_info); put_page_type(page); return 0; } -- 2.30.2